#ifndef NUMBER_RECOG_H
#define NUMBER_RECOG_H

/*
TODO:
1. Number_recog::pre_processing need to be modified to suit the real situation,
    which is the number is on the robot armor!
2. to be tested
*/


#include <armor_recog.hpp>
#include <stdio.h>
#include <fstream>
#include <opencv2/videoio.hpp>
#include <opencv2/video.hpp>
#include <letter_recog.hpp>

using namespace cv::ml;

class Number_recog {
    public:
    Number_recog();

    /// \brief  get the videos/photos, whose reference are saved in the $filename_videos_txt \
    ///    for each line, start with its tag and the corresponding path to the video/photo
    /// \param filename_video_txt   the txt file that contains the path to the videos/photos as trainning input,
    ///                           for each line start with the tag value, space, path
    /// \param data_filename_dataset_save   the path of the file to save the dataset after processing
    bool prepare_data(Mat &src, RotatedRect &bound, ofstream &out_data, int tag);

    /// \brief   read existing model/Ptr<KNearest> object
    /// \param filename_model   path to the model
    bool read_model(const string &filename_model);

    /// \brief   train model using the dataset created by \function prepare_data
    /// \param filename_dataset   path to dataset
    /// \param filename_model_to_save   path to save the trained model
    void train_model(const string &filename_dataset, 
                     const string &filename_model_to_save);

    /// \brief   predict the input image using model, make sure the model is loaded
    /// \param to_predict   input image
    int predict(const Mat &to_predict, RotatedRect bounding_box);


    private:
    HOGDescriptor hog;
    Ptr<SVM> model;
    const int KNN_K = 10;

    cv::Mat pre_processing(const Mat &src, RotatedRect bounding_box);

    cv::Mat decrease_to_size(const Mat &src, int size);

    void write(ofstream &outDataBase, const Mat &toWrite, int tag);
};

int test(int COLOR, int tag, string &pathOfDescriptionFile);

#endif